#include "StdAfx.h"
#include "Camera.h"
void Camera::setFOV(Vector3& position, Vector3& up, Vector3& target, GLfloat fovy, GLfloat aspect, GLfloat nearPlane, GLfloat farPlane)
{
	//this->position = position;
	this->target_local = Vector3(0, 0, -(position - target).Length());
	this->up = up;
	projectionMatrix.SetPerspective(fovy, aspect, nearPlane, farPlane);
	worldMatrix.SetTranslation(position);
	//worldMatrix.SetIdentity();
}
void Camera::moveLeft()
{
	//translationMatrix.SetTranslation(-TRANSLATE_STEP, 0, 0);
	translationMatrix.SetTranslation(-xaxis * TRANSLATE_STEP);
	move();
}
void Camera::moveRight()
{
	//translationMatrix.SetTranslation(TRANSLATE_STEP, 0, 0);
	translationMatrix.SetTranslation(xaxis* TRANSLATE_STEP);
	
	move();
}
void Camera::moveForward()
{
	translationMatrix.SetTranslation(-zaxis * TRANSLATE_STEP);
	move();
}
void Camera::moveBackward()
{
	translationMatrix.SetTranslation(zaxis * TRANSLATE_STEP);
	move();
}

void Camera::RotateLeft()
{
	rotationMatrix.SetRotationY(ROTATE_STEP);
	rotate();
}
void Camera::RotateRight()
{
	rotationMatrix.SetRotationY(-ROTATE_STEP);
	rotate();
}
void Camera::RotateUp()
{ 
	rotationMatrix.SetRotationX(-ROTATE_STEP);
	rotate();
}
void Camera::RotateDown()
{
	rotationMatrix.SetRotationX(ROTATE_STEP);
	rotate();
}

void Camera::rotate()
{
	target_local = rotationMatrix * Vector4(target_local, 1.0f);
}

Camera::Camera(void)
{
}

Camera::~Camera(void)
{
}


Matrix Camera::getViewMatrix()
{
	// View matrix
	Vector3 position = getPosition(), target = getTarget();
  	calcAxis(position, target);
	Matrix* v = &viewMatrix;
	v->m[0][0]=xaxis.x;				v->m[1][0]=yaxis.x;				v->m[2][0]=zaxis.x;				v->m[3][0]=0;
	v->m[0][1]=xaxis.y;				v->m[1][1]=yaxis.y;				v->m[2][1]=zaxis.y;				v->m[3][1]=0;
	v->m[0][2]=xaxis.z;				v->m[1][2]=yaxis.z;				v->m[2][2]=zaxis.z;				v->m[3][2]=0;
	v->m[0][3]=-position.Dot(xaxis);v->m[1][3]=-position.Dot(yaxis);v->m[2][3]=-position.Dot(zaxis);v->m[3][3]=1;
	//
	return viewMatrix;
}
Matrix& Camera::getProjectionMatrix()
{
	return projectionMatrix;
}

Vector3 Camera::getPosition()
{
	Vector3 position;
	position = Vector4(0, 0, 0, 1) * worldMatrix;
	return position;
}


Vector3 Camera::getTarget()
{

	Vector3 target;
	target = Vector4(target_local, 1) * worldMatrix;
	//esLogMessage("x: %f; y: %f, z: %f \n", target->x, target->y, target->z);
	return target;
}

void Camera::calcAxis(Vector3& position, Vector3& target)
{
	zaxis = (position - target).Normalize();
	xaxis = (up.Cross(zaxis)).Normalize();
	yaxis = zaxis.Cross(xaxis).Normalize();
}